package com.leiyuee.distributed.lock.controller;

import com.leiyuee.distributed.lock.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StockController {

    @Autowired
    private StockService stockService;

    @GetMapping("stock/deduct")
    public String deduct(){
        this.stockService.deduct();
        return "减库存:";
    }



    private static ReentrantLock lock = new ReentrantLock();

    public  void doSth(){
        try {
            boolean b = lock.tryLock();
        }catch (Exception e){

        }finally {
            lock.unlock();
        }
    }
    /**
     * 读写锁：如果写锁被占用了，就只能等待释放了再加读或写锁
     * 读锁能同时申请
     */
    public void wrLock(){
        ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        readWriteLock.writeLock().tryLock();
        readWriteLock.readLock().tryLock();
    }
    /**
     * CountDownLatch：使用给定的计数进行初始化，调用countDown（）方法，每次减少1，
     * await方法一直阻塞到当前计数达到零 然后释放所有的等待线程
     */
    public void countDownLatch(){
        CountDownLatch countDownLatch = new CountDownLatch(8);
        for (int i = 0; i < countDownLatch.getCount(); i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "OUT");
                //计数器减少1 --countDown()
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        try {
            countDownLatch.await();//等待计数器归零
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"=======全部出来了");
    }

    /**
     * CyclicBarrier: 循环栅栏，初始化设置目标障碍数，达到目标次数就执行预定的任务
     */
    public void cyclicBarrier(){
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10,()->{
            System.out.println("恭喜完成");
        });
        for (int i = 0; i <10;i++){
            new Thread(() ->{
                System.out.println(Thread.currentThread().getName()+"1次");
                try {
                    cyclicBarrier.await();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
        //重置计数
        cyclicBarrier.reset();
        //可以通过写代码再次执行任务
    }

    /**
     * Semaphore: 信号量，总共只有多少许可
     */
    public void semaphore(){
        Semaphore semaphore = new Semaphore(10);
        for (int i = 0; i <10;i++){
            new Thread(() ->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢到");
                    TimeUnit.SECONDS.sleep(100);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }

    public void phaser(){
        Phaser phaser = new MyPhase();
        for (int i = 0; i <10;i++){
            new Thread(() ->{
                phaser.register();
                System.out.println(Thread.currentThread().getName()+"步骤1");
                phaser.arriveAndAwaitAdvance();
                System.out.println(Thread.currentThread().getName()+"步骤2");
                phaser.arriveAndAwaitAdvance();
                System.out.println(Thread.currentThread().getName()+"步骤3");
                phaser.arriveAndAwaitAdvance();

            },String.valueOf(i)).start();
        }
    }
    static class MyPhase extends Phaser{
        /**
         *
         * @param phase the current phase number on entry to this method,
         * before this phaser is advanced
         * @param registeredParties the current number of registered parties
         * @return 如果此方法返回true ，则此移相器将在提前时设置为最终终止状态，并且对isTerminated后续调用将返回 true。
         */
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            if (phase ==0){
                System.out.println("0");
                return false;
            }else if (phase ==1){
                System.out.println("1");
                return false;
            }else if (phase ==2){
                System.out.println("2");
                return true;
            }
            return true;
        }
    }
}
